﻿using Serilog;
using Serilog.Debugging;
using Serilog.Events;
using Serilog.Formatting.Json;
using Serilog.Sinks.Elasticsearch;
using Serilog.Sinks.File;
using Serilog.Sinks.SystemConsole.Themes;
using System;
using Sustainalytics.Admin.Synchronization.Utility;
using System.Threading;

namespace Sustainalytics.News.BusinessLogic
{
    public class NewsServiceSerilog
    {
        private static Lazy<NewsServiceSerilog> _lazyLog = new Lazy<NewsServiceSerilog>(InitLog, LazyThreadSafetyMode.ExecutionAndPublication);
        private readonly ILogger _logger;

        public static NewsServiceSerilog Log
        {
            get
            {
                return _lazyLog.Value;
            }
        }

        public static NewsServiceSerilog InitLog()
        {
            var log = new NewsServiceSerilog();

            log.Ping();

            return log;

        }

        public NewsServiceSerilog()
        {
            var loggerConfig = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.Console(theme: SystemConsoleTheme.Literate)
                  .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200"))
                  {
                      IndexFormat = "testnews-{0:yyyy.MM.dd}",
                      AutoRegisterTemplate = true,
                      RegisterTemplateFailure = RegisterTemplateRecovery.IndexAnyway,
                      FailureCallback = e => Console.WriteLine("Unable to submit event " + e.MessageTemplate),
                      EmitEventFailure = EmitEventFailureHandling.WriteToSelfLog |
                                         EmitEventFailureHandling.WriteToFailureSink |
                                         EmitEventFailureHandling.RaiseCallback,
                      FailureSink = new FileSink("../failuresNewsService-" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", new JsonFormatter(), null)
                  });
            _logger = loggerConfig.CreateLogger();

            SelfLog.Enable(Console.Error);
        }
        
        public void Ping()
        {
            var eventId = 1;

            if (_logger.IsEnabled(LogEventLevel.Debug))
                _logger.Debug("Ping {0}", eventId);
        }
        
        public void StartAutoUnpublish(string currentDT, string referenceDT)
        {
            var eventId = 1103;
            string formatedmessage = String.Format("StartAutoUnpublish {0}, {1}, {2}", eventId, currentDT, referenceDT);
            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information(formatedmessage);
        }

        public void StopAutoUnpublish(string currentDT, string nextRunDT)
        {
            var eventId = 1104;
            string formatedmessage = String.Format("StopAutoUnpublish {0}, {1}, {2}", eventId, currentDT, nextRunDT);
            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information(formatedmessage);
        }

        public void StartAutoUnpublishError(Exception exception)
        {
            Guard.ArgumentNotNull(exception, "exception");
            if (_logger.IsEnabled(LogEventLevel.Error))
            {
                this.StartAutoUnpublishError(exception.ToString());
            }
        }
        public void StartAutoUnpublishError(string exceptionMessage)
        {
            var eventId = 1105;
            string formatedmessage = String.Format("StartAutoUnpublishError {0}, {1}", eventId, exceptionMessage);
            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error(formatedmessage);
        }

        public void GetNotification()
        {
            var eventId = 1200;
            string formatedmessage = String.Format("GetNotification {0}", eventId);
            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information(formatedmessage);
        }

        public void GetNotificationSuccess()
        {
            var eventId = 1201;
            string formatedmessage = String.Format("PatchNewsSuccess {0}", eventId);
            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information(formatedmessage);
        }

        public void GetNotificationError(Exception exception)
        {
            Guard.ArgumentNotNull(exception, "exception");
            if (_logger.IsEnabled(LogEventLevel.Error))
            {
                this.GetNotificationError(exception.ToString());
            }
        }
        public void GetNotificationError(string exceptionMessage)
        {
            var eventId = 1202;
            string formatedmessage = String.Format("GetNotificationError {0}, {1}", eventId, exceptionMessage);
            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error(formatedmessage);
        }

        public void UpsertNotification(string notification)
        {
            var eventId = 1300;
            string formatedmessage = String.Format("UpsertNotification {0}, {1}", eventId, notification);
            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information(formatedmessage);
        }

        public void UpsertNotificationSuccess(string notification)
        {
            var eventId = 1301;
            string formatedmessage = String.Format("UpsertNotificationSuccess {0}, {1}", eventId, notification);
            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information(formatedmessage);
        }

        public void UpsertNotificationError(string notification, Exception exception)
        {
            Guard.ArgumentNotNull(exception, "exception");
            if (_logger.IsEnabled(LogEventLevel.Error))
            {
                this.UpsertNotificationError(notification, exception.ToString());
            }
        }
        public void UpsertNotificationError(string notification, string exceptionMessage)
        {
            var eventId = 1302;
            string formatedmessage = String.Format("UpsertNotificationError {0}, {1}, {2}", eventId, notification, exceptionMessage);
            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error(formatedmessage);
        }
        
    }
}
